Skip to content

chore: Describe RBAC rules, remove unnecessary rules#767

Open
NickLarsenNZ wants to merge 10 commits intomainfrom
chore/rbac-review
Open

chore: Describe RBAC rules, remove unnecessary rules#767
NickLarsenNZ wants to merge 10 commits intomainfrom
chore/rbac-review

Conversation

@NickLarsenNZ
Copy link
Member

@NickLarsenNZ NickLarsenNZ commented Mar 25, 2026

Part of stackabletech/issues#798

Note

This was initially generated by a coding assistant to see how well it can inspect code and review the RBAC rules. the changes will be properly checked before reviews are requested.

  • Document each rule
  • Check the docs make sense. Rewrite where necessary
  • Remove unnecessary permissions
  • Attach explanations to PR description
  • Run all tests
  • Split operator and product roles into separate files

Explanation

The file deploy/helm/airflow-operator/templates/roles.yaml was audited. Every RBAC rule now
has a comment explaining why it exists. The following unnecessary permissions were removed:

Permission removed Reason
batch/jobs (entire rule) Leftover from the old AirflowDB controller removed in PR #322. DB init now runs as part of the scheduler entrypoint. The delete_orphaned_resources framework does attempt cleanup on Jobs, but silently skips on 403, and since no Jobs are ever created there is nothing to clean up.
pods from operator ClusterRole The operator never directly creates or manages Pods. Pods are created by StatefulSets. (Pods remain in the product ClusterRole where Airflow's KubernetesExecutor needs them.)
endpoints Never created or managed by the operator. Auto-created by Kubernetes for Services. Present since the original operator template boilerplate.
update verb on all operator ClusterRole resources The operator exclusively uses Server-Side Apply (SSA = PATCH), never PUT (update/replace). Confirmed by searching for client.update() calls — none exist.
watch on rolebindings, poddisruptionbudgets, listeners These resources are not watched by the controller (no .owns() or .watches() call). They only need verbs for SSA (create + patch) and orphan cleanup (list + delete), plus get for the ReconciliationPaused path.
patch on the primary CRD (airflowclusters) The operator only patches airflowclusters/status (separate rule), never the main resource itself. The controller only needs get + list + watch on the main CRD.
get on configmaps, secrets, serviceaccounts for the product ClusterRole Is never read by Airflow pods (I checked docker-images and demos too)

They were a bit too verbose
- Add missing description
- Remove `get`, it is never used
- Make list/watch unconditional
This was never needed, and if an end-user does happen to need their code reading secrets/configmaps, they should create the applicable role and binding.
@NickLarsenNZ
Copy link
Member Author

--- PASS: kuttl (4970.37s)
    --- PASS: kuttl/harness (0.00s)
        --- PASS: kuttl/harness/external-access_airflow-2.9.3_openshift-false_executor-kubernetes (179.57s)
        --- PASS: kuttl/harness/mount-dags-gitsync_airflow-latest-3.1.6_openshift-false_executor-celery_access-https (460.77s)
        --- PASS: kuttl/harness/triggerer_airflow-latest-3.1.6_openshift-false_executor-kubernetes (198.18s)
        --- PASS: kuttl/harness/logging_airflow-3.0.6_openshift-false_executor-kubernetes (600.71s)
        --- PASS: kuttl/harness/triggerer_airflow-latest-3.1.6_openshift-false_executor-celery (213.50s)
        --- PASS: kuttl/harness/orphaned-resources_airflow-latest-3.1.6_openshift-false (169.61s)
        --- PASS: kuttl/harness/oidc_airflow-latest-3.1.6_openshift-false (183.35s)
        --- PASS: kuttl/harness/versioning_airflow-latest-3.1.6_openshift-false (247.38s)
        --- PASS: kuttl/harness/external-access_airflow-2.9.3_openshift-false_executor-celery (198.15s)
        --- PASS: kuttl/harness/ldap_airflow-latest-3.1.6_ldap-authentication-server-verification-tls_openshift-false_executor-kubernetes (182.02s)
        --- PASS: kuttl/harness/ldap_airflow-latest-3.1.6_ldap-authentication-server-verification-tls_openshift-false_executor-celery (212.92s)
        --- PASS: kuttl/harness/ldap_airflow-latest-3.1.6_ldap-authentication-no-tls_openshift-false_executor-kubernetes (180.69s)
        --- PASS: kuttl/harness/ldap_airflow-latest-3.1.6_ldap-authentication-no-tls_openshift-false_executor-celery (210.72s)
        --- PASS: kuttl/harness/mount-dags-configmap_airflow-latest-3.1.6_openshift-false_executor-kubernetes (162.25s)
        --- PASS: kuttl/harness/mount-dags-configmap_airflow-latest-3.1.6_openshift-false_executor-celery (199.03s)
        --- PASS: kuttl/harness/logging_airflow-3.1.6_openshift-false_executor-celery (213.08s)
        --- PASS: kuttl/harness/ldap_airflow-latest-3.1.6_ldap-authentication-insecure-tls_openshift-false_executor-kubernetes (191.28s)
        --- PASS: kuttl/harness/logging_airflow-3.1.6_openshift-false_executor-kubernetes (558.96s)
        --- PASS: kuttl/harness/smoke_airflow-2.9.3_openshift-false_executor-kubernetes (166.22s)
        --- PASS: kuttl/harness/smoke_airflow-3.0.6_openshift-false_executor-celery (207.16s)
        --- PASS: kuttl/harness/smoke_airflow-2.9.3_openshift-false_executor-celery (188.86s)
        --- PASS: kuttl/harness/overrides_airflow-latest-3.1.6_openshift-false (169.67s)
        --- PASS: kuttl/harness/smoke_airflow-3.0.6_openshift-false_executor-kubernetes (195.95s)
        --- PASS: kuttl/harness/mount-dags-gitsync_airflow-latest-3.1.6_openshift-false_executor-kubernetes_access-ssh (241.88s)
        --- PASS: kuttl/harness/ldap_airflow-latest-3.1.6_ldap-authentication-insecure-tls_openshift-false_executor-celery (204.61s)
        --- PASS: kuttl/harness/mount-dags-gitsync_airflow-latest-3.1.6_openshift-false_executor-kubernetes_access-https (234.38s)
        --- PASS: kuttl/harness/opa_airflow-3.1.6_opa-latest-1.12.3_openshift-false (190.43s)
        --- PASS: kuttl/harness/mount-dags-gitsync_airflow-latest-3.1.6_openshift-false_executor-celery_access-ssh (261.13s)
        --- PASS: kuttl/harness/opa_airflow-3.0.6_opa-latest-1.12.3_openshift-false (175.55s)
        --- PASS: kuttl/harness/cluster-operation_airflow-latest-3.1.6_openshift-false (217.04s)
        --- PASS: kuttl/harness/smoke_airflow-3.1.6_openshift-false_executor-kubernetes (197.15s)
        --- PASS: kuttl/harness/opa_airflow-2.9.3_opa-latest-1.12.3_openshift-false (176.74s)
        --- PASS: kuttl/harness/smoke_airflow-3.1.6_openshift-false_executor-celery (188.69s)
        --- PASS: kuttl/harness/remote-logging_airflow-latest-3.1.6_openshift-false_executor-celery (218.57s)
        --- PASS: kuttl/harness/logging_airflow-2.9.3_openshift-false_executor-celery (256.23s)
        --- PASS: kuttl/harness/remote-logging_airflow-latest-3.1.6_openshift-false_executor-kubernetes (186.47s)
        --- PASS: kuttl/harness/external-access_airflow-3.1.6_openshift-false_executor-celery (136.40s)
        --- PASS: kuttl/harness/logging_airflow-3.0.6_openshift-false_executor-celery (277.41s)
        --- PASS: kuttl/harness/resources_airflow-latest-3.1.6_openshift-false (136.35s)
        --- PASS: kuttl/harness/external-access_airflow-3.1.6_openshift-false_executor-kubernetes (137.54s)
        --- PASS: kuttl/harness/logging_airflow-2.9.3_openshift-false_executor-kubernetes (688.94s)
        --- PASS: kuttl/harness/external-access_airflow-3.0.6_openshift-false_executor-kubernetes (134.27s)
        --- PASS: kuttl/harness/external-access_airflow-3.0.6_openshift-false_executor-celery (138.70s)

@NickLarsenNZ NickLarsenNZ marked this pull request as ready for review March 27, 2026 12:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant